<script setup lang="ts">

import {ref} from "vue";
import {ElNotification, FormInstance, FormRules, UploadProps, UploadRawFile} from "element-plus";
import axios from "axios";
import {ServerHost, loginUser} from "@/main.js";
import {v4 as uuidv4} from "uuid";
import {Plus} from "@element-plus/icons-vue";
import {downloadImg} from "@/utils";
import {createFilter} from "vite";

// post or edit
const props = defineProps(['type', 'goods'])

const goods = ref({
  id: "",
  name: "",
  priceCent: 0,
  img: "",
  introduction: "",
  sellerId: "",
  inventory: 1,
  sales: 0,
  addTime: new Date(),
  type: "",
});
const imgUrl = ref("")

const isLoadingList = ref(false)
if (props.type === 'edit') {
  goods.value = props.goods
  goods.value.addTime = new Date(props.goods.addTime)
  goods.value.priceCent /= 100
  // 下载封面
  if (props.goods.img) {
    isLoadingList.value = true
    downloadImg(props.goods.img, "goodsImg/")
        .then(res => {
          if (res.status === 200) {
            const type = props.goods.img.split('.')[1]
            let mime: string
            if ((['jpg', 'jpeg'] as any).includes('jpg'))
              mime = 'image/jpeg'
            else
              mime = `image/${type}`
            const blob = new Blob([res.data], {type: mime})
            imgFile = new File([blob], props.goods.img, {type: mime})
            imgUrl.value = URL.createObjectURL(imgFile)
            console.log(imgUrl.value)
            isLoadingList.value = false
          }
        })
  }

}

if (props.type === 'new') {
  // 每隔1s更新一次发布时间
  setInterval(() => {
    goods.value.addTime = new Date()
  }, 1000)
}

const goodsFormRef = ref<FormInstance>()

const validateIsNull = (rule: any, value: any, callback: any) => {
  let showName = "";
  switch (rule.field) {
    case "name":
      showName = "商品名称";
      break
    case "priceCent":
      showName = "商品价格"
      break
    case "introduction":
      showName = "商品介绍"
      break
    case "inventory":
      showName = "商品库存"
      break
    case "type":
      showName = "商品类型"
      break
  }
  console.log(rule.field)
  if (!value) {
    callback(new Error(`请输入${showName}`))
  } else {
    callback()
  }
}

const goodsRules = ref<FormRules<typeof goods>>({
  name: [{validator: validateIsNull, trigger: 'blur'}],
  priceCent: [{validator: validateIsNull, trigger: 'blur'}],
  introduction: [{validator: validateIsNull, trigger: 'blur'}],
  inventory: [{validator: validateIsNull, trigger: 'blur'}],
  type: [{validator: validateIsNull, trigger: 'blur'}],
})

let imgFile: File

const verifyImg = (rawFile: UploadRawFile) => {
  return !(rawFile.size > 1024 * 1024)
}

const isChangeImg = ref(false)
const onAddImg: UploadProps['beforeUpload'] = (rawFile: UploadRawFile) => {

  if (!verifyImg(rawFile)) {
    ElNotification({
      title: '图片大小不能超过1MB',
      type: 'warning',
      position: 'bottom-right',
    })
    return
  }

  console.log(rawFile)
  imgFile = rawFile
  imgUrl.value = URL.createObjectURL(rawFile)

  if (props.type === 'edit') {
    isChangeImg.value = true
  }

}

const onPostNewGoods = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate(valid => {
    if (valid) {

      //有封面则传封面
      goods.value.img = uploadImg().toString()

      // 生成uuid
      goods.value.id = uuidv4()
      goods.value.sellerId = loginUser.value.id
      goods.value.priceCent *= 100

      console.log('start submit!')
      console.log(goods.value)
      axios.post(`${ServerHost}/postNewGoods`, goods.value)
          .then((res) => {
            if (res.status === 200) {
              // 清空内容
              goods.value.name = ""
              goods.value.priceCent = 0
              goods.value.introduction = ""
              goods.value.inventory = 0
              goods.value.sales = 0
              goods.value.type = ""
              imgUrl.value = ""
              imgFile = undefined
              ElNotification({
                title: '商品已上架',
                type: 'success',
                position: 'bottom-right',
              })
            } else {
              ElNotification({
                title: '商品上架失败',
                type: 'error',
                position: 'bottom-right',
              })
            }
          })
    } else {
      console.log('error submit!')
    }
  })
}

const emit = defineEmits(["getValue"])

const onUpdateGood = (formEl: FormInstance | undefined) => {
  if (!formEl) return
  formEl.validate(valid => {
    if (valid) {

      //有封面改动则传封面
      if (isChangeImg.value) {
        goods.value.img = uploadImg().toString()
      }
      goods.value.priceCent *= 100

      console.log(goods.value)
      console.log('start submit!')
      axios.post(`${ServerHost}/updateGoods`, goods.value)
          .then((res) => {
            if (res.status === 200) {
              emit("getValue", true)
              ElNotification({
                title: '商品修改成功',
                type: 'success',
                position: 'bottom-right',
              })
            } else {
              ElNotification({
                title: '商品修改失败',
                type: 'error',
                position: 'bottom-right',
              })
            }
          })


    } else {
      console.log('error submit!')
    }

  })
}

// 覆盖自带的上传行为
const onImgUpload = () => {
  console.log('onImgUpload')
}

const uploadImg = (): String => {
  let fileName = ""
  console.log(imgFile)
  if (!(typeof imgFile === "undefined")) {
    fileName += uuidv4()
    const fileFormat = imgFile.type.split("/")[1]
    fileName += '.' + fileFormat

    axios.post(`${ServerHost}/postFile`, {file: imgFile}, {
      headers: {
        "Content-Type": "multipart/form-data",
      },
      params: {
        "name": fileName,
        "path": "goodsImg/"
      }
    })
        .then(res => {
          if (res.status === 200) {
            ElNotification({
              title: '图片上传成功',
              type: 'success',
              position: 'bottom-right',
            })
          } else {
            ElNotification({
              title: '图片上传失败',
              type: 'error',
              position: 'bottom-right',
            })
          }
        })
    return fileName
  } else {
    return ""
  }
}

const onDeleteGoods = () => {
  console.log(goods.value.id)
  axios.post(`${ServerHost}/deleteGoods?id=${goods.value.id}`,)
      .then(res => {
        if (res.status === 200) {
          emit("getValue", true)
          ElNotification({
            title: '商品删除成功',
            type: 'success',
            position: 'bottom-right',
          })
        } else {
          ElNotification({
            title: '商品删除失败',
            type: 'success',
            position: 'bottom-right',
          })
        }
      })
}

// 获取已有的商品类型列表
const goodTypeList = ref([])
axios.get(`${ServerHost}/getGoodsTypeList`)
    .then(res => {
      if (res.status === 200) {
        goodTypeList.value = []
        res.data.forEach(type => {
          goodTypeList.value.push({value: type})
        })
        console.log(goodTypeList.value)
      }
    })

const querySearchType = (queryString: string, cb: any) => {
  const results = goodTypeList.value.filter((type: { value: "" }) => {
    return type.value.includes(queryString);
  })
  cb(results)
}

</script>

<template>
  <el-form ref="goodsFormRef" :rules="goodsRules" :model="goods">
    <el-form-item label="商品图片" prop="title">
      <div class="goods-img-upload">
        <el-upload
            drag
            class=""
            :http-request="onImgUpload"
            :before-upload="onAddImg"
            :show-file-list="false"
            v-loading="isLoadingList"
        >
          <el-image v-if="imgUrl" fit="contain" :src="imgUrl" class="goods-img"
                    alt="Goods Img"/>
          <el-icon v-else class="img-uploader-icon">
            <Plus/>
          </el-icon>
        </el-upload>
      </div>
    </el-form-item>
    <el-form-item label="商品名称" prop="name">
      <el-input v-model="goods.name" placeholder="请输入商品名称"></el-input>
    </el-form-item>
    <el-form-item label="商品价格" prop="priceCent">
      <el-input v-model="goods.priceCent" type="number" placeholder="请输入商品价格"></el-input>
    </el-form-item>
    <el-form-item label="商品库存" prop="inventory">
      <!--   只能输入整数   -->
      <el-input v-model="goods.inventory" type="text" placeholder="请输入商品库存"
                oninput="this.value = this.value.replace(/[^0-9]/g, '');"></el-input>
    </el-form-item>
    <el-form-item label="商品介绍" prop="introduction">
      <el-input v-model="goods.introduction" type="textarea" :rows="10" placeholder="请输入商品介绍"></el-input>
    </el-form-item>
    <el-form-item label="商品类型" prop="type">
      <el-autocomplete v-model="goods.type" placeholder="请输入商品类型"
                       :fetch-suggestions="querySearchType"></el-autocomplete>
    </el-form-item>
    <el-form-item label="上架时间">
      <el-date-picker
          v-model="goods.addTime"
          type="datetime"
          :readonly="true"
      />
    </el-form-item>
    <el-form-item>
      <el-button v-if="props.type === 'new'" type="primary" @click="onPostNewGoods(goodsFormRef)">发布</el-button>
      <el-button v-if="props.type === 'edit'" type="primary" @click="onUpdateGood(goodsFormRef)">确认修改</el-button>
      <el-popconfirm
          v-if="props.type === 'edit'"
          width="auto"
          title="确定要删除吗"
          confirm-button-text="确认删除"
          confirm-button-type="danger"
          cancel-button-text="取消"
          placement="top"
          @confirm="onDeleteGoods"
      >
        <template #reference>
          <el-button type="danger">删除</el-button>
        </template>
      </el-popconfirm>
    </el-form-item>
  </el-form>
</template>

<style scoped lang="scss">

$img-img-size: 200px;

.goods-img-upload {
  width: $img-img-size;
  height: $img-img-size;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
  border: 1px solid var(--el-border-color);
  border-radius: 4px;
}

.goods-img-upload:hover {
  border-color: var(--el-color-primary);
}

.goods-img, .img-uploader-icon {
  width: $img-img-size;
  height: $img-img-size;
}

</style>
